#include "main.h"


// 初始化名为s的栈，初始化成功，返回0，否则返回1。
int init_stack(Stack* s) {
	(*s) = malloc(sizeof(struct stack));
	int *num = (int*)malloc(sizeof(int) * STACK_MAX_SIZE);
	(*s)->base = num;
	if (!(*s)->base) {
		return 1;
	}
	(*s)->top = (*s)->base;
	(*s)->number_of_elements = STACK_MAX_SIZE;
	return 0;
}

// 入栈。返回值表示是否压栈成功：0，成功；1，不成功。
int push(Stack s, char operator_or_operand) {
	//判断是否栈满
	if (s->top - s->base >= s->number_of_elements) {
		return 1;
	}
	*(s->top) = operator_or_operand;
	s->top++;
	return 0;
}

// 出栈。返回值表示是否出栈成功：0，成功，1，不成功。
int pop(Stack s, char* p_operator_or_operand) {
	if (s->top == s->base) {
		return 1;
	}
	s->top--;
	*p_operator_or_operand = *(s->top);
	return 0;
}

// 只返回栈顶元素，通过result变量返回栈顶元素的值。函数返回值用于表示执行状态：0，成功；1，不成功。
int get_top(Stack s, char* result) {
	if (s->top == s->base) {
		return 1;
	}
	*result = *(s->top - 1);
	return 0;
}

// 判断字符symbol是否操作符。如果symbol是操作符，返回1，否则返回0。
bool is_operator(char symbol) {
	char operator[7] = { '+','-','*','/','(',')','#' };
	for (int i = 0; i < 7; ++i)
	{
		if (operator[i] == symbol)
		{
			return 1;
		}
	}
	return 0;
}

// 判断字符symbol是否操作数。如果symbol是操作数，返回1，否则返回0。
bool is_operand(char symbol) {
	char operand[10] = { '0','1','2','3','4','5','6','7','8','9' };
	for (int i = 0; i < 10; ++i)
	{
		if (operand[i] == symbol)
		{
			return 1;
		}
	}
	return 0;
}

//判断操作符
int compare(char k, char l) {
	int i, j;
	char atChar[][7] = {
		/*运算符之间的优先级制作成一张表格*/
		{'>', '>', '<', '<', '<', '>', '>'},
		{'>', '>', '<', '<', '<', '>', '>'},
		{'>', '>', '>', '>', '<', '>', '>'},
		{'>', '>', '>', '>', '<', '>', '>'},
		{'<', '<', '<', '<', '<', '=', '0'},
		{'>', '>', '>', '>', '0', '>', '>'},
		{'<', '<', '<', '<', '<', '0', '='}
	};
	switch (k) {
	case '+': i = 0; break;
	case '-': i = 1; break;
	case '*': i = 2; break;
	case '/': i = 3; break;
	case '(': i = 4; break;
	case ')': i = 5; break;
	case '#': i = 6; break;
	}
	switch (l) {
	case '+':j = 0; break;
	case '-':j = 1; break;
	case '*':j = 2; break;
	case '/':j = 3; break;
	case '(':j = 4; break;
	case ')':j = 5; break;
	case '#':j = 6; break;
	}
	switch (atChar[i][j]) {
	case '>':
		return 1;
	case '<':
		return -1;
	case '=':
		return 0;
	}
}

//进行计算的函数
int caculate(char operator, char left, char right, int* result) {
	int i, j;
	switch (left) {
	case'0': i = 0; break;
	case'1': i = 1; break;
	case'2': i = 2; break;
	case'3': i = 3; break;
	case'4': i = 4; break;
	case'5': i = 5; break;
	case'6': i = 6; break;
	case'7': i = 7; break;
	case'8': i = 8; break;
	case'9': i = 9; break;
	}
	switch (right) {
	case'0': j = 0; break;
	case'1': j = 1; break;
	case'2': j = 2; break;
	case'3': j = 3; break;
	case'4': j = 4; break;
	case'5': j = 5; break;
	case'6': j = 6; break;
	case'7': j = 7; break;
	case'8': j = 8; break;
	case'9': j = 9; break;
	}

	switch (operator) {
	case '+':*result = i + j; break;
	case '-':*result = i - j; break;
	case '*':*result = i * j; break;
	case '/':
		if (j != 0) {
			*result = i / j;
		}
		else {
			printf("除数不能为零！\n");
			exit(0);
		}
		break;
	}
	return 0;
}
// 最主要的函数，用于计算表达式的值，比如#3*(2+6)/4#。
// 返回值表示求值状态：0，合法表达式，成功求值；1，表达式不合法。
// result变量用于返回计算结果。
int evaluate(char* expression, int* result) {
	Stack T;
	Stack P;
	char left_operand;
	char right_operand;
	init_stack(&T);
	init_stack(&P);
	int char_position = 0;
	push(T, expression[char_position]);
	char_position += 1;
	char top;
	char w = expression[char_position];
	while (w != '#' || top != '#')
	{
		if (is_operand(w))
		{
			push(P, w);
			char_position += 1;
			w = expression[char_position];
		}
		if (is_operator(w))
		{
			char c;
			get_top(T, &c);
			char Total;
			int RESULT;
			switch (compare(c, w)) {
			case -1:
				push(T, w);
				w = expression[++char_position];
				break;
			case 0:
				pop(T, &c);
				w = expression[++char_position];
				break;
			case 1:
				pop(P, &right_operand);
				pop(P, &left_operand);
				pop(T, &c);
				if (c == '#' || left_operand == 0) {
					*result = 1;
					return *result;
				}
				else {
					caculate(c, left_operand, right_operand, &RESULT);
					Total = RESULT + 48;
					push(P, Total);
				}
				break;
			}
		}
		get_top(T, &top);
	}
	get_top(P, &top);
	*result = top - 48;
	return *result;
}




int main() {

}